home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 25 / Cream of the Crop 25.iso / doom / quake_ad.zip / BSP2M011.ZIP / BSP2M010.C next >
C/C++ Source or Header  |  1997-01-16  |  10KB  |  371 lines

  1.  
  2. #include "cmdlib.h"
  3. #include "mathlib.h"
  4. #include "bspfile.h"
  5. #include "mathlib.h"
  6.  
  7. #define MAX_FACE_EDGES 20
  8.  
  9. typedef struct epair_s
  10. {
  11.     struct epair_s    *next;
  12.     char    *key;
  13.     char    *value;
  14. } epair_t;
  15.  
  16. float b2m_ver = (float)0.1;    // BSP2MAP version
  17. int verbose1, verbose2, verbose3 = 0;
  18.  
  19. //--------------
  20.  
  21. void GetEdges(int ledge, dedge_t *edge)
  22. {
  23.     if (dsurfedges[ledge]>0) {
  24.         *edge = dedges[dsurfedges[ledge]];
  25.     } else {
  26.         edge->v[0] = dedges[-dsurfedges[ledge]].v[1];
  27.         edge->v[1] = dedges[-dsurfedges[ledge]].v[0];
  28.     }
  29. }
  30.  
  31. void ProcessFace(int face)
  32. {
  33.     short n_face_edges;
  34.     int ledge, ledge2;
  35.     dedge_t edges[MAX_FACE_EDGES];
  36.     dvertex_t vert_beg[MAX_FACE_EDGES];
  37.     dvertex_t vert_end[MAX_FACE_EDGES];
  38.     vec3_t normal, v1, v2, v3;
  39.     miptex_t *p_miptex;
  40.     dmiptexlump_t *head_miptex;
  41.     texinfo_t *p_texinfo;
  42.     float x_off, y_off, rotation, x_scale, y_scale;
  43.     static int gi=0;
  44.     char gs[12];
  45.     char texname[18];
  46.  
  47.     n_face_edges = dfaces[face].numedges;
  48.     if (n_face_edges < 3)
  49.         Error ("too few edges for face");
  50.     if (n_face_edges > MAX_FACE_EDGES)
  51.         Error ("too many edges for face");
  52.  
  53.     for (ledge=0; ledge < n_face_edges; ledge++) {
  54.         GetEdges(ledge + dfaces[face].firstedge, &edges[ledge]);
  55.         vert_beg[ledge] = dvertexes[edges[ledge].v[0]];
  56.         vert_end[ledge] = dvertexes[edges[ledge].v[1]];
  57.         if (verbose1)
  58.             printf(" // edge %d, ledge %d [%4.2f %4.2f %4.2f] [%4.2f %4.2f
  59. %4.2f]\n",
  60.                     ledge, ledge + dfaces[face].firstedge,
  61.                     vert_beg[ledge].point[0], vert_beg[ledge].point[1],
  62. vert_beg[ledge].point[2],
  63.                     vert_end[ledge].point[0], vert_end[ledge].point[1],
  64. vert_end[ledge].point[2]);
  65.     }
  66.  
  67.     _VectorCopy(dplanes[dfaces[face].planenum].normal, normal);
  68.     if (verbose1) {
  69.         printf(" // dfaces[face].planenum = %d,  side = %d\n",
  70. dfaces[face].planenum, dfaces[face].side);
  71.         printf(" // normal ( %4.2f %4.2f %4.2f ) type %d\n",
  72.             normal[0], normal[1], normal[2],
  73. dplanes[dfaces[face].planenum].type);
  74.     }
  75.     VectorScale (normal, (float)2, normal);
  76.     if (!dfaces[face].side)
  77.         VectorInverse(normal);
  78.  
  79.     for (ledge2=1; ledge2 < n_face_edges-2; ledge2++) {
  80.         _VectorSubtract(vert_end[0].point, vert_beg[0].point, v1);
  81.         _VectorSubtract(vert_end[ledge2].point, vert_beg[ledge2].point, v2);
  82.         VectorNormalize(v1);
  83.         VectorNormalize(v2);
  84.         if (!VectorCompare(v1, v2))
  85.             break;
  86.     }
  87.     head_miptex = (dmiptexlump_t *)dtexdata;
  88.     p_texinfo = &texinfo[dfaces[face].texinfo];
  89.     p_miptex = (miptex_t *)((((byte
  90. *)dtexdata))+(head_miptex->dataofs[p_texinfo->miptex]));
  91.     strcpy(texname, p_miptex->name);
  92.     strupr(texname);
  93.     if (verbose2)
  94.         printf(" // texinfo ( %4.2f %4.2f %4.2f %4.2f ) ( %4.2f %4.2f %4.2f
  95. %4.2f )\n",
  96.                 p_texinfo->vecs[0][0], p_texinfo->vecs[0][1],
  97. p_texinfo->vecs[0][2], p_texinfo->vecs[0][3],
  98.                 p_texinfo->vecs[0][0], p_texinfo->vecs[0][1],
  99. p_texinfo->vecs[0][2], p_texinfo->vecs[0][3]);
  100.     //here must calc x_off y_off rotation x_scale y_scale from p_texinfo->vecs !
  101.     x_off = y_off = rotation = (float)0;
  102.     x_scale = y_scale = (float)1;
  103.  
  104.     printf(" {\n");
  105.     printf("  ( %4.0f %4.0f %4.0f ) ( %4.0f %4.0f %4.0f ) ( %4.0f %4.0f %4.0f )
  106. %s %.0f %.0f %.0f %.2f %.2f\n",
  107.             vert_beg[0].point[0], vert_beg[0].point[1], vert_beg[0].point[2],
  108.             vert_end[0].point[0], vert_end[0].point[1], vert_end[0].point[2],
  109.             vert_end[ledge2].point[0], vert_end[ledge2].point[1],
  110. vert_end[ledge2].point[2],
  111.             texname,
  112.             x_off, y_off, rotation, x_scale, y_scale);
  113.     for (ledge=0; ledge < n_face_edges; ledge++) {
  114.         if (ledge==0) {
  115.             _VectorSubtract(vert_end[n_face_edges-1].point,
  116. vert_beg[n_face_edges-1].point, v1);
  117.             _VectorSubtract(vert_end[ledge].point, vert_beg[ledge].point, v2);
  118.             VectorNormalize(v1);
  119.             VectorNormalize(v2);
  120.             if (VectorCompare(v1, v2))
  121.                 continue;
  122.         } else {
  123.             _VectorSubtract(vert_end[ledge-1].point, vert_beg[ledge-1].point,
  124. v1);
  125.             _VectorSubtract(vert_end[ledge].point, vert_beg[ledge].point, v2);
  126.             VectorNormalize(v1);
  127.             VectorNormalize(v2);
  128.             if (VectorCompare(v1, v2))
  129.                 continue;
  130.         }
  131.         _VectorAdd(vert_end[ledge].point, normal, v2);
  132.         printf("  ( %4.0f %4.0f %4.0f ) ( %4.0f %4.0f %4.0f ) ( %4.0f %4.0f
  133. %4.0f ) %s 0 0 0 1 1\n",
  134.                 vert_end[ledge].point[0], vert_end[ledge].point[1],
  135. vert_end[ledge].point[2],
  136.                 vert_beg[ledge].point[0], vert_beg[ledge].point[1],
  137. vert_beg[ledge].point[2],
  138.                 v2[0], v2[1], v2[2],
  139.                 texname);
  140.     }
  141.     _VectorAdd(vert_beg[0].point, normal, v2);
  142.     _VectorAdd(vert_end[0].point, normal, v1);
  143.     _VectorAdd(vert_end[ledge2].point, normal, v3);
  144.     if (verbose3)
  145.         sprintf(gs, "tx%04x", gi++);
  146.     printf("  ( %4.0f %4.0f %4.0f ) ( %4.0f %4.0f %4.0f ) ( %4.0f %4.0f %4.0f )
  147. %s 0 0 0 1 1\n",
  148.             v1[0], v1[1], v1[2],
  149.             v2[0], v2[1], v2[2],
  150.             v3[0], v3[1], v3[2],
  151.             !verbose3 ? texname : gs);
  152.     printf(" }\n");
  153. }
  154.  
  155. void ProcessModel(int model)
  156. {
  157.     int face;
  158.     printf(" // total brushes: %d\n", dmodels[model].numfaces);
  159.     for (face=0; face < dmodels[model].numfaces; face++)
  160.         ProcessFace(face + dmodels[model].firstface);
  161. }
  162.  
  163. #define    MAXTOKEN    128
  164.  
  165. char    token[MAXTOKEN];
  166. qboolean    unget;
  167. char    *script_p;
  168. int        scriptline;
  169. epair_t    epair;
  170.  
  171. void    StartTokenParsing (char *data) // this function comes from qbsp\map.c
  172. {
  173.     scriptline = 1;
  174.     script_p = data;
  175.     unget = false;
  176. }
  177.  
  178. qboolean GetToken (qboolean crossline) // this function comes from qbsp\map.c
  179. {
  180.     char    *token_p;
  181.  
  182.     if (unget)                         // is a token allready waiting?
  183.         return true;
  184.  
  185. //
  186. // skip space
  187. //
  188. skipspace:
  189.     while (*script_p <= 32)
  190.     {
  191.         if (!*script_p)
  192.         {
  193.             if (!crossline)
  194.                 Error ("Line %i is incomplete",scriptline);
  195.             return false;
  196.         }
  197.         if (*script_p++ == '\n')
  198.         {
  199.             if (!crossline)
  200.                 Error ("Line %i is incomplete",scriptline);
  201.             scriptline++;
  202.         }
  203.     }
  204.  
  205.     if (script_p[0] == '/' && script_p[1] == '/')    // comment field
  206.     {
  207.         if (!crossline)
  208.             Error ("Line %i is incomplete\n",scriptline);
  209.         while (*script_p++ != '\n')
  210.             if (!*script_p)
  211.             {
  212.                 if (!crossline)
  213.                     Error ("Line %i is incomplete",scriptline);
  214.                 return false;
  215.             }
  216.         goto skipspace;
  217.     }
  218.  
  219. //
  220. // copy token
  221. //
  222.     token_p = token;
  223.  
  224.     if (*script_p == '"')
  225.     {
  226.         script_p++;
  227.         while ( *script_p != '"' )
  228.         {
  229.             if (!*script_p)
  230.                 Error ("EOF inside quoted token");
  231.             *token_p++ = *script_p++;
  232.             if (token_p > &token[MAXTOKEN-1])
  233.                 Error ("Token too large on line %i",scriptline);
  234.         }
  235.         script_p++;
  236.     }
  237.     else while ( *script_p > 32 )
  238.     {
  239.         *token_p++ = *script_p++;
  240.         if (token_p > &token[MAXTOKEN-1])
  241.             Error ("Token too large on line %i",scriptline);
  242.     }
  243.  
  244.     *token_p = 0;
  245.     
  246.     return true;
  247. }
  248.  
  249. void UngetToken () // this function comes from qbsp\map.c
  250. {
  251.     unget = true;
  252. }
  253.  
  254. void _ParseEpair (void)
  255. {
  256.     memset (&epair, 0, sizeof(epair_t));
  257.     
  258.     if (strlen(token) >= MAX_KEY-1)
  259.         Error ("ParseEpar: token too long");
  260.     epair.key = copystring(token);
  261.     GetToken (false);
  262.     if (strlen(token) >= MAX_VALUE-1)
  263.         Error ("ParseEpar: token too long");
  264.     epair.value = copystring(token);
  265. }
  266.  
  267. int ParseEnt(void)
  268. {
  269.     int model;
  270.     int keys;
  271.  
  272.     model = -1;
  273.     keys = 0;
  274.  
  275.     if (!GetToken (true))
  276.         return -2;
  277.  
  278.     if (strcmp (token, "{") )
  279.         Error ("ProcessEnts: { not found");
  280.     
  281.     do {
  282.         if (!GetToken (true))
  283.             Error ("ParseEnt: EOF without closing brace");
  284.         if (!strcmp (token, "}") )
  285.             break;
  286.         _ParseEpair();
  287.         if (!keys) {
  288.             keys++;
  289.             printf ("{\n");
  290.         }
  291.         if (!strcmp(epair.key, "model")) {
  292.             model = atoi(&epair.value[1]);
  293.             if (verbose1 || verbose2 || verbose3)
  294.                 printf (" // \"%s\" \"%s\"\n", epair.key, epair.value);
  295.         } else {
  296.             printf (" \"%s\" \"%s\"\n", epair.key, epair.value);
  297.         }
  298.         if (!strcmp(epair.key, "classname") && !strcmp(epair.value,
  299. "worldspawn")) {
  300.             model = 0;
  301.         }
  302.     } while (1);
  303.  
  304.     if (model >= 0)
  305.         ProcessModel(model);
  306.  
  307.     if (keys)
  308.         printf ("}\n");
  309.  
  310.     return model;
  311. }
  312.  
  313. void MakeMap (void)
  314. {
  315.     int model;
  316.     StartTokenParsing(dentdata);
  317.     while (1) {
  318.         model = ParseEnt();
  319.         if (model == -2)
  320.             break;
  321.     }
  322. }
  323.  
  324. //--------------
  325.  
  326. void main (int argc, char **argv)
  327. {
  328.     int         i;
  329.     char        source[1024];
  330.     double        start, end;
  331.  
  332.     for (i=1 ; i<argc ; i++) {
  333.         if (!strcmp(argv[i], "-v1")) {
  334.             printf ("//verbose1 = true\n");
  335.             verbose1 = 1;
  336.         }
  337.         else if (!strcmp(argv[i], "-v2")) {
  338.             printf ("//verbose2 = true\n");
  339.             verbose2 = 1;
  340.         }
  341.         else if (!strcmp(argv[i], "-v3")) {
  342.             printf ("//verbose3 = true\n");
  343.             verbose3 = 1;
  344.         }
  345.         else if (argv[i][0] == '-')
  346.             Error ("Unknown option \"%s\"", argv[i]);
  347.         else
  348.             break;
  349.     }
  350.  
  351.     if (i != argc - 1) {
  352.         printf ("BSP2MAP %.2f  Created by Janis Jagars (Disastry)\n", b2m_ver);
  353.         Error ("usage: bsp2map [-v1] [-v2] [-v3] bspfile > mapfile");
  354.     }
  355.  
  356.     start = I_FloatTime ();
  357.  
  358.     printf ("//---------------------\n");
  359.     strcpy (source, argv[i]);
  360.     DefaultExtension (source, ".bsp");
  361.     printf ("//Created from %s by BSP2MAP %.2f\n", source, b2m_ver);
  362.  
  363.     LoadBSPFile (source);       
  364.  
  365.     MakeMap ();
  366.  
  367.     end = I_FloatTime ();
  368.     printf ("//%5.1f seconds elapsed\n", end-start);
  369.     printf ("//---------------------\n");
  370. }
  371.